package com.qf.commons.core.utils;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;

import java.lang.reflect.Method;

/**
 * description: 解析Spel表达式
 * author: Ken
 * 公众号：Java架构栈
 */
@Slf4j
public class SpelUtils {

    //表达式的解析器对象
    private static ExpressionParser parser = new SpelExpressionParser();
    //解析方法形参名称对象
    private static LocalVariableTableParameterNameDiscoverer nameDiscoverer = new LocalVariableTableParameterNameDiscoverer();

    /**
     * 解析指定的表达式
     * @param <T>
     * @return
     */
    public static <T> T getValue(String spel, Method method, Object[] vals, Class<T> defaultCls, T defaultVal){

        //获得形参名称
        String[] parameterNames = nameDiscoverer.getParameterNames(method);

        //求值上下文对象 - 存放着相关的key - value
        EvaluationContext evaluationContext = new StandardEvaluationContext();
        for (int i = 0; i < parameterNames.length; i++) {
            evaluationContext.setVariable(parameterNames[i], vals[i]);
        }

        //获得表达式的值
        T value = null;
        try {
            //解析表达式
            Expression expression = parser.parseExpression(spel);
            value = expression.getValue(evaluationContext, defaultCls);
            log.info("[spel parse] - {} 解析后的结果：{}", spel, value);
        } catch (Exception e) {
            return defaultVal;
        }
        return value;
    }
}
